package com.javastudy.jdkfeature.jdk5.autoboxing;

import java.util.ArrayList;

/**
 * 自动装箱/拆箱(Autoboxing/unboxing)
 * 自动装箱：基本类型自动转换为包装类
 * 自动拆包：包装类自动转换为基本类型
 * 功能：自动装箱/拆箱
 * 编译器自动进行基本类型和对应的包装类型进行转换
 * byte      <-->   Byte
 * short     <-->   Short
 * int       <-->   Integer
 * long      <-->   Long
 * float     <-->   Float
 * double    <-->   Double
 * char      <-->   Character
 * boolean   <-->   Boolean
 */
public class AutoBoxingOrUnBoxing {
    /**
     * 这里我们以Integer为实例
     */
    public void jdk14() {
        //在jdk1.4中,初始话一个值类型对应的包装类，你需要这么写
        Integer integer = new Integer(1);
        int i = integer.intValue();
        //如果你需要在数组中添加一个数值类型的话，你还需要把他转成基础类型
        new ArrayList().add(new Integer(i));
    }

    public void jdk15() {
        //在jdk1.5中你可以这么写; int --> Integer
        Integer integer = 1;
        // Integer --> int
        int i = integer;
        //这里你可以直接添加数值类型
        new ArrayList().add(i);
    }

    public static void main(String[] args) {
        /*
         * 这里有一些有趣的特性，享元模式，
         * 经过装箱和解箱的对象只要大小在-128到127之间（byte类型的范围之间）
         * 都会在jvm内存的对象缓存池里形成记录，下次有装箱和解箱行为的对象，
         * 都会直接指向这个缓存次里的对象
         */

        Integer num1 = 20;
        int num2 = new Integer(20);
        System.out.println(num1 == num2); //true @answer1
        Integer int1 = new Integer(20);
        Integer int2 = new Integer(20);
        System.out.println(int1 == int2); // false @answer2
        System.out.println(num1 == int1); //false @answer3
        System.out.println(num1 == int1 * 1);//true @answer4


        //->answer1:true num1和num2都经过了装箱和解箱，都指向缓存池里的对象20
        //->answer2:false int1和int2 没经过装箱和解箱，2个是不同的对象，比较他们的引用地址肯定也不一样
        //->ansewr3:false 一个在的引用地址指向缓存池，一个是指向对象[20]的引用地址2个也不相等
        //->answer4:true 后面int1经过了解箱然后*1运算，然后又装箱成Integer类型，所以他的引用地址也是缓存池里的地址
    }
}
